package cz.cacek.ebook;

import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;
import javax.microedition.rms.RecordStoreFullException;
import javax.microedition.rms.RecordStoreNotFoundException;

/**
 * Library. Holds book names in ebook application.
 * Class is final because of calling getClass().getResourceAsStream(...) in constructor.
 * @author Tom� Darmovzal [tomas.darmovzal (at) seznam.cz]
 * @author Josef Cacek [josef.cacek (at) atlas.cz]
 * @author $Author: kwart $
 * @version $Revision: 1.10 $
 * @created $Date: 2007/08/30 11:25:22 $
 */
public final class Library {

	//private String[] books;
	private Book activeBook;
	//private static Library instance;

	private int bookIdx = Utils.NO_BOOK_SELECTED;

	private LibraryInfo libInfo;

//	private Library(){
//		books = new String[0];
//	}
	/**
	 * Reads information about library
	 * @throws IOException
	 *             library information file doesn't exist
	 */
//	private Library(InputStream tmpIS) throws IOException {
//		if (tmpIS == null) {
//			throw new RuntimeException("Cannot get library info");
//		}
//		DataInputStream tmpDIS = new DataInputStream(tmpIS);
//		try{
//			int count = tmpDIS.readInt();
//			if(Utils.INFO){
//				Utils.info("count:"+count);
//			}
//			books = new String[count];
//			for (int i = 0; i < count; i++) {
//				books[i] = tmpDIS.readUTF();
//			}
//		}finally{
//			tmpDIS.close();
//		}
//	}

//	/**
//	 * Returns singleton of this class
//	 * @return singleton
//	 */
//	public synchronized static Library getInstance() {
//		if (instance==null) {
//			try {
//				InputStream tmpIS = Library.class.getResourceAsStream("/"+Utils.DATA_FOLDER+"/"+Utils.LIBRARY_FILE);
//
//				instance = tmpIS != null ?  new Library(tmpIS) :new Library();
//			} catch (IOException ioe) {
//				throw new RuntimeException(ioe.getMessage());
//			}
//		}
//		return instance;
//	}

	public Library(LibraryInfo libInfo) {
		super();
		this.libInfo = libInfo;
	}

	/**
	 * Count of books in library
	 * @return Pocet knih v knihovne
	 */
	public int getBookCount() {
		return this.libInfo.getBookCount();
	}

	/**
	 * Returns name of book on a given position
	 * @param anIdx
	 * @return name of book on a given position
	 */
	public String getBookName(int anIdx) {
		if (anIdx < 0)
			throw new RuntimeException("Negative book index");
		if (anIdx >= getBookCount())
			throw new RuntimeException("Book index too large");
		//return books[anIdx];
		return this.libInfo.getBook(anIdx).getName();
	}

	/**
	 * Returns book on a given position
	 * @param anIdx
	 * @return book on a given position
	 */
	public Book getBook(int anIdx) {
		if (anIdx>=0 && (bookIdx != anIdx || activeBook == null)) {
			bookIdx = anIdx;
			BookInfo bInfo = this.libInfo.getBook(anIdx);
			activeBook = new Book(bInfo.getId(),bInfo.getName());
			activeBook.setPosition(getActivePosition());
		}
		return activeBook;
	}


	public Book getActive() {
		return activeBook;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		return "Library (books=" + this.getBookCount() + ")";
	}

	/**
	 * Creates bookmark for active book from library
	 */
	private int getActivePosition() {
		int tmpResult = 0;
		if (bookIdx>=0) {
			try {
				RecordStore tmpBookmarksRs = getBookmarksRS();
				final byte[] tmpBytes = tmpBookmarksRs.getRecord(1);
				tmpBookmarksRs.closeRecordStore();
				final int n=bookIdx*4;
				tmpResult = 0;
				for (int i=0; i<4; i++) {
					tmpResult = tmpResult | (tmpBytes[i+n] & 0xff) << (8*i);
				}

			} catch (Exception e) {
				Utils.error(e);
			}
		}
		return tmpResult;
	}

	/**
	 * Creates bookmark for active book from library
	 */
	public void savePosition(final int aPos) {
		if (bookIdx<0) {
			return;
		}
		try {
			RecordStore tmpBookmarksRs = getBookmarksRS();
			final byte[] tmpBytes = tmpBookmarksRs.getRecord(1);
			final int n=bookIdx*4;
			tmpBytes[n]= (byte) (aPos & 0xff);
			tmpBytes[n+1]= (byte) ((aPos & 0xff00) >> 8);
			tmpBytes[n+2]= (byte) ((aPos & 0xff0000) >> 16);
			tmpBytes[n+3]= (byte) ((aPos & 0xff000000) >> 24);
			tmpBookmarksRs.setRecord(1, tmpBytes, 0, tmpBytes.length);
			tmpBookmarksRs.closeRecordStore();
		} catch (Exception e) {
			Utils.error(e);
		}
	}

	/**
	 * @return bookmarks record store
	 * @throws RecordStoreFullException
	 * @throws RecordStoreNotFoundException
	 * @throws RecordStoreException
	 */
	private RecordStore getBookmarksRS() throws RecordStoreFullException, RecordStoreNotFoundException, RecordStoreException {
		RecordStore tmpRS = null;
		tmpRS = RecordStore.openRecordStore(Utils.STORE_BOOKMARKS, true);
		if (tmpRS.getNumRecords()==0) {
			final byte[] tmpBytes = new byte[getBookCount()*4];
			tmpRS.addRecord(tmpBytes, 0, tmpBytes.length);
		}
		return tmpRS;
	}

	/**
	 * @return the bookIdx
	 */
	public int getBookIdx() {
		return bookIdx;
	}

	/**
	 * @param bookIdx the bookIdx to set
	 */
	public void setBookIdx(int bookIdx) {
		this.bookIdx = bookIdx;
	}
}
